package com.tuanzi.loan.business.repository.family.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.tuanzi.loan.business.entity.CurrentUser;
import com.tuanzi.loan.business.entity.family.LoanLargeAmountPartnerControl;
import com.tuanzi.loan.business.repository.family.LoanLargeH5StatRepository;
import com.tuanzi.loan.core.repository.JOOQBaseRepositoryPlus;
import com.tuanzi.loan.vo.request.family.LoanLargeH5StatSearchRequest;
import com.tuanzi.loan.vo.response.family.LoanLargeAmountPartnerControlSearchResponse;
import com.tuanzi.loan.vo.response.family.LoanLargeH5StatSearchResponse;
import org.apache.commons.lang3.StringUtils;
import org.jooq.SelectField;
import org.jooq.impl.DSL;
import org.jooq.impl.TableImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.tuanzi.loan.generated.jooq.loan.Tables.LOAN_CHANNEL_ND_INFO;
import static com.tuanzi.loan.generated.jooq.loan.Tables.LOAN_LARGE_AMOUNT_PARTNER_CONTROL;
import static com.tuanzi.loan.generated.jooq.stat.tables.LoanLargeH5OutsideStat.LOAN_LARGE_H5_OUTSIDE_STAT;

@Repository
public class LoanLargeH5StatRepositoryImpl extends JOOQBaseRepositoryPlus implements LoanLargeH5StatRepository {

    @Autowired
    StringRedisTemplate stringRedisTemplate;


    @Override
    protected TableImpl getTable() {
        return LOAN_LARGE_H5_OUTSIDE_STAT;
    }

    @Override
    public Page<LoanLargeH5StatSearchResponse> list(LoanLargeH5StatSearchRequest searchRequest, Pageable pageable) {
        List<SelectField<?>> selectFields = new ArrayList<>();
        selectFields.add(LOAN_LARGE_H5_OUTSIDE_STAT.CREATE_DATE);
        selectFields.add(DSL.sum(LOAN_LARGE_H5_OUTSIDE_STAT.FILL_USER_COUNT).as("fill_user_count"));
        selectFields.add(DSL.sum(LOAN_LARGE_H5_OUTSIDE_STAT.HIGH_QUALITY_USER_COUNT).as("high_quality_user_count"));
        selectFields.add(DSL.sum(LOAN_LARGE_H5_OUTSIDE_STAT.SUCCESS_USER_COUNT).as("success_user_count"));
        selectFields.add(DSL.sum(LOAN_LARGE_H5_OUTSIDE_STAT.UPDATE_USER_COUNT).as("update_user_count"));
        selectFields.add(DSL.sum(LOAN_LARGE_H5_OUTSIDE_STAT.TOTAL_AMOUNT).as("total_amount"));

        if (!(searchRequest.getPrd_name() != null && searchRequest.getPrd_name().contains("-2000"))){
            selectFields.add(LOAN_LARGE_H5_OUTSIDE_STAT.PRD_NAME);
            if (searchRequest.getPrd_name()!=null&&!searchRequest.getPrd_name().contains("")){
                in(LOAN_LARGE_H5_OUTSIDE_STAT.PRD_NAME,searchRequest.getPrd_name());
            }
            groupBy(LOAN_LARGE_H5_OUTSIDE_STAT.PRD_NAME);
        }

        if (!(searchRequest.getChannel() != null && searchRequest.getChannel().contains("-2000"))){
            selectFields.add(LOAN_LARGE_H5_OUTSIDE_STAT.CHANNEL);
            if (searchRequest.getChannel()!=null&&!searchRequest.getChannel().contains("")){
                in(LOAN_LARGE_H5_OUTSIDE_STAT.CHANNEL,searchRequest.getChannel());
            }
            groupBy(LOAN_LARGE_H5_OUTSIDE_STAT.CHANNEL);
        }
        SelectField[] selectArray = new SelectField[selectFields.size()];
        selectFields.toArray(selectArray);
        fields(selectArray);
        ge(LOAN_LARGE_H5_OUTSIDE_STAT.CREATE_DATE,searchRequest.getStartDate());
        le(LOAN_LARGE_H5_OUTSIDE_STAT.CREATE_DATE,searchRequest.getEndDate());

        //如果当前用户=合作方  获取当前用户所属甲方
        LoanLargeAmountPartnerControlSearchResponse resp = findCurrentNameInLargeAmount();
        if (resp != null){
            eq(LOAN_LARGE_H5_OUTSIDE_STAT.PRD_ID,resp.getPartnertype());
            if (null != resp.getChannel_n()){
                List<String> lists = Lists.newArrayList();
                Arrays.stream(resp.getChannel_n().split(",")).forEach(k->{
                    lists.add(k.trim());
                });
                in(LOAN_LARGE_H5_OUTSIDE_STAT.CHANNEL,lists);
            }
        }
        groupBy(LOAN_LARGE_H5_OUTSIDE_STAT.CREATE_DATE);
        orderBy(LOAN_LARGE_H5_OUTSIDE_STAT.CREATE_DATE, Sort.Direction.DESC);
        return search(pageable, record -> {
            LoanLargeH5StatSearchResponse response = new LoanLargeH5StatSearchResponse();
            response.setCreate_date(record.get(LOAN_LARGE_H5_OUTSIDE_STAT.CREATE_DATE));
            if (searchRequest.getPrd_name()!=null && searchRequest.getPrd_name().contains("-2000")){
                response.setPrd_name("全部");
            }else{
                response.setPrd_name(record.get(LOAN_LARGE_H5_OUTSIDE_STAT.PRD_NAME));
            }
            if (searchRequest.getChannel()!=null && searchRequest.getChannel().contains("-2000")){
                response.setChannel("全部");
            }else{
                response.setChannel(record.get(LOAN_LARGE_H5_OUTSIDE_STAT.CHANNEL));
            }
            response.setFill_user_count(record.get(LOAN_LARGE_H5_OUTSIDE_STAT.field("fill_user_count"),Integer.class));
            response.setHigh_quality_user_count(record.get(LOAN_LARGE_H5_OUTSIDE_STAT.field("high_quality_user_count"),Integer.class));
            response.setSuccess_user_count(record.get(LOAN_LARGE_H5_OUTSIDE_STAT.field("success_user_count"),Integer.class));
            response.setTotal_amount(record.get(LOAN_LARGE_H5_OUTSIDE_STAT.field("total_amount"),BigDecimal.class));
            response.setUpdate_user_count(record.get(LOAN_LARGE_H5_OUTSIDE_STAT.field("update_user_count"),Integer.class));
            return response;
        });

    }

    @Override
    public List<String> queryProName() {
        return dslContext.selectDistinct(LOAN_LARGE_H5_OUTSIDE_STAT.PRD_NAME).from(LOAN_LARGE_H5_OUTSIDE_STAT)
                .where(LOAN_LARGE_H5_OUTSIDE_STAT.PRD_NAME.isNotNull()).fetchInto(String.class);
    }
    @Override
    public List<String> selectChannelInfo() {
        return dslContext.selectDistinct(LOAN_CHANNEL_ND_INFO.CHANNEL_ND)
                .from(LOAN_CHANNEL_ND_INFO)
                .where(LOAN_CHANNEL_ND_INFO.CHANNEL_ND.isNotNull().and(LOAN_CHANNEL_ND_INFO.CHANNEL_ND.notEqual(""))).fetch().into(String.class);
    }

    @Override
    public LoanLargeAmountPartnerControlSearchResponse findCurrentNameInLargeAmount() {
        for (LoanLargeAmountPartnerControlSearchResponse resp: getListResponse()) {
            if (resp.getUsername().equals(CurrentUser.get().getUsername())){
                return resp;
            }
        }
        return null;
    }


    private List<LoanLargeAmountPartnerControlSearchResponse> getListResponse(){
        String listRedis = stringRedisTemplate.opsForValue().get("loan_large_amount_partner:all");
        if (StringUtils.isBlank(listRedis) ){
            List<LoanLargeAmountPartnerControlSearchResponse> list = findAllControl();
            stringRedisTemplate.opsForValue().set("loan_large_amount_partner:all", JSON.toJSONString(list),2, TimeUnit.HOURS);
            return list;
        }else{
            return JSONObject.parseArray(listRedis,LoanLargeAmountPartnerControlSearchResponse.class);
        }
    }


    public List<LoanLargeAmountPartnerControlSearchResponse> findAllControl() {
        List<LoanLargeAmountPartnerControlSearchResponse>
                responseList = Lists.newArrayList();
        for (LoanLargeAmountPartnerControl loan:findAll()) {
            LoanLargeAmountPartnerControlSearchResponse response = new LoanLargeAmountPartnerControlSearchResponse();
            BeanUtils.copyProperties(loan,response);
            responseList.add(response);
        }
        return responseList;
    }

    private List<LoanLargeAmountPartnerControl> findAll(){
        return dslContext.select(LOAN_LARGE_AMOUNT_PARTNER_CONTROL.fields()).from(LOAN_LARGE_AMOUNT_PARTNER_CONTROL).fetchInto(LoanLargeAmountPartnerControl.class);
    }
}
